﻿namespace Typps
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Web.Script.Serialization;
    using System.Web.UI.WebControls;

    public static class EffectsJavaScriptConverter
    {
        #region Methods

        public static ArrayList Serialize(EffectsCollection sec)
        {
            if (sec == null)
                throw new ArgumentNullException("you need to provide a EffectsCollection");
            return AddToDictionary(sec);
        }

        static ArrayList AddToDictionary(EffectsCollection sec)
        {
            ArrayList itemList = new ArrayList();
            Dictionary<string, object> dic = null;
            foreach (BaseEffect eff in sec)
            {
                switch (eff.Name)
                {
                    case "Blind":
                        dic = new Dictionary<string, object>();
                        Blind b = (Blind)eff;
                        dic.Add("effect", b.Name);
                        dic.Add("transition", ToPascalCase(b.Transition.ToString()));
                        dic.Add("duration", b.Duration);
                        dic.Add("from", GetUnitValueIfPercent(b.From));
                        dic.Add("to", GetUnitValueIfPercent(b.To));
                        dic.Add("fps", b.FPS);
                        dic.Add("toggle", b.Toggle);
                        dic.Add("useCssBox", b.UseCssBox);
                        dic.Add("runMode", (int)b.RunMode);
                        if (!string.IsNullOrEmpty(b.Setup))
                            dic.Add("setup", b.Setup);
                        if (!string.IsNullOrEmpty(b.Finish))
                            dic.Add("finish", b.Finish);
                        itemList.Add(dic);
                        break;
                    case "Fade":
                        dic = new Dictionary<string, object>();
                        Fade f = (Fade)eff;
                        dic.Add("effect", f.Name);
                        dic.Add("transition", ToPascalCase(f.Transition.ToString()));
                        dic.Add("duration", f.Duration);
                        dic.Add("from", GetUnitValueIfPercent(f.From));
                        dic.Add("to", GetUnitValueIfPercent(f.To));
                        dic.Add("fps", f.FPS);
                        dic.Add("toggle", f.Toggle);
                        dic.Add("runMode", (int)f.RunMode);
                        if (!string.IsNullOrEmpty(f.Setup))
                            dic.Add("setup", f.Setup);
                        if (!string.IsNullOrEmpty(f.Finish))
                            dic.Add("finish",f.Finish);
                        itemList.Add(dic);
                        break;
                    case "Grow":
                        dic = new Dictionary<string, object>();
                        Grow g = (Grow)eff;
                        dic.Add("effect", g.Name);
                        dic.Add("transition", ToPascalCase(g.Transition.ToString()));
                        dic.Add("duration", g.Duration);
                        dic.Add("from", GetUnitValueIfPercent(g.From));
                        dic.Add("to", GetUnitValueIfPercent(g.To));
                        dic.Add("fps", g.FPS);
                        dic.Add("toggle", g.Toggle);
                        dic.Add("growCenter", g.GrowCenter);
                        dic.Add("useCssBox", g.UseCssBox);
                        dic.Add("runMode", (int)g.RunMode);
                        if (!string.IsNullOrEmpty(g.Setup))
                            dic.Add("setup", g.Setup);
                        if (!string.IsNullOrEmpty(g.Finish))
                            dic.Add("finish", g.Finish);
                        itemList.Add(dic);
                        break;
                    case "Highlight":
                        dic = new Dictionary<string, object>();
                        Highlight h = (Highlight)eff;
                        dic.Add("effect", h.Name);
                        dic.Add("transition", ToPascalCase(h.Transition.ToString()));
                        dic.Add("duration", h.Duration);
                        dic.Add("from", h.From);
                        dic.Add("to", h.To);
                        dic.Add("fps", h.FPS);
                        dic.Add("toggle", h.Toggle);
                        dic.Add("restoreColor", h.RestoreColor);
                        dic.Add("runMode", (int)h.RunMode);
                        if (!string.IsNullOrEmpty(h.Setup))
                            dic.Add("setup", h.Setup);
                        if (!string.IsNullOrEmpty(h.Finish))
                            dic.Add("finish", h.Finish);
                        itemList.Add(dic);
                        break;
                    case "Shake":
                        dic = new Dictionary<string, object>();
                        Shake sh = (Shake)eff;
                        dic.Add("effect", sh.Name);
                        dic.Add("transition", ToPascalCase(sh.Transition.ToString()));
                        dic.Add("duration", sh.Duration);
                        dic.Add("fps", sh.FPS);
                        dic.Add("runMode", (int)sh.RunMode);
                        if (!string.IsNullOrEmpty(sh.Setup))
                            dic.Add("setup", sh.Setup);
                        if (!string.IsNullOrEmpty(sh.Finish))
                            dic.Add("finish", sh.Finish);
                        itemList.Add(dic);
                        break;
                    case "Slide":
                        dic = new Dictionary<string, object>();
                        Slide sl = (Slide)eff;
                        dic.Add("effect", sl.Name);
                        dic.Add("transition", ToPascalCase(sl.Transition.ToString()));
                        dic.Add("duration", sl.Duration);
                        dic.Add("from", GetUnitValueIfPercent(sl.From));
                        dic.Add("to", GetUnitValueIfPercent(sl.To));
                        dic.Add("fps", sl.FPS);
                        dic.Add("toggle", sl.Toggle);
                        dic.Add("horizontal", sl.Horizontal);
                        dic.Add("runMode", (int)sl.RunMode);
                        if (!string.IsNullOrEmpty(sl.Setup))
                            dic.Add("setup", sl.Setup);
                        if (!string.IsNullOrEmpty(sl.Finish))
                            dic.Add("finish", sl.Finish);
                        itemList.Add(dic);
                        break;
                    case "Squish":
                        dic = new Dictionary<string, object>();
                        Squish sq = (Squish)eff;
                        dic.Add("effect", sq.Name);
                        dic.Add("transition", ToPascalCase(sq.Transition.ToString()));
                        dic.Add("duration", sq.Duration);
                        dic.Add("from", GetUnitValueIfPercent(sq.From));
                        dic.Add("to", GetUnitValueIfPercent(sq.To));
                        dic.Add("fps", sq.FPS);
                        dic.Add("toggle", sq.Toggle);
                        dic.Add("useCssBox", sq.UseCssBox);
                        dic.Add("runMode", (int)sq.RunMode);
                        if (!string.IsNullOrEmpty(sq.Setup))
                            dic.Add("setup", sq.Setup);
                        if (!string.IsNullOrEmpty(sq.Finish))
                            dic.Add("finish", sq.Finish);
                        itemList.Add(dic);
                        break;
                    case "Color":
                        dic = new Dictionary<string, object>();
                        ColorEffect ce = (ColorEffect)eff;
                        dic.Add("effect", ce.Name);
                        dic.Add("transition", ToPascalCase(ce.Transition.ToString()));
                        dic.Add("duration", ce.Duration);
                        dic.Add("startColor", ce.StartColor);
                        dic.Add("endColor", ce.EndColor);
                        dic.Add("toggle", ce.Toggle);
                        dic.Add("fps", ce.FPS);
                        dic.Add("runMode", (int)ce.RunMode);
                        if (!string.IsNullOrEmpty(ce.Setup))
                            dic.Add("setup", ce.Setup);
                        if (!string.IsNullOrEmpty(ce.Finish))
                            dic.Add("finish", ce.Finish);
                        itemList.Add(dic);
                        break;
                    case "Move":
                        dic = new Dictionary<string, object>();
                        Move m = (Move)eff;
                        dic.Add("effect", m.Name);
                        dic.Add("transition", ToPascalCase(m.Transition.ToString()));
                        dic.Add("duration", m.Duration);
                        dic.Add("fps", m.FPS);
                        dic.Add("fromX", m.FromX.Value);
                        dic.Add("fromY", m.FromY.Value);
                        dic.Add("toX", m.ToX.Value);
                        dic.Add("toY", m.ToY.Value);
                        dic.Add("toggle", m.Toggle);
                        dic.Add("runMode", (int)m.RunMode);
                        if(!string.IsNullOrEmpty(m.Setup))
                            dic.Add("setup", m.Setup);
                        if(!string.IsNullOrEmpty(m.Finish))
                            dic.Add("finish", m.Finish);
                        itemList.Add(dic);
                        break;
                    case "Size":
                        dic = new Dictionary<string, object>();
                        Size s = (Size)eff;
                        dic.Add("effect", s.Name);
                        dic.Add("transition", ToPascalCase(s.Transition.ToString()));
                        dic.Add("duration", s.Duration);
                        dic.Add("fps", s.FPS);
                        dic.Add("fromWidth", s.FromWidth.Value);
                        dic.Add("fromHeight", s.FromHeight.Value);
                        dic.Add("toWidth", s.ToWidth.Value);
                        dic.Add("toHeight", s.ToHeight.Value);
                        dic.Add("scaleContent", s.ScaleContent);
                        dic.Add("toggle", s.Toggle);
                        dic.Add("runMode", (int)s.RunMode);
                        if (!string.IsNullOrEmpty(s.Setup))
                            dic.Add("setup", s.Setup);
                        if (!string.IsNullOrEmpty(s.Finish))
                            dic.Add("finish", s.Finish);
                        itemList.Add(dic);
                        break;
                    case "Fold":
                        dic = new Dictionary<string, object>();
                        Fold fo = (Fold)eff;
                        dic.Add("effect", fo.Name);
                        dic.Add("toggle", fo.Toggle);
                        dic.Add("runMode", (int)fo.RunMode);
                        if (!string.IsNullOrEmpty(fo.Setup))
                            dic.Add("setup", fo.Setup);
                        if (!string.IsNullOrEmpty(fo.Finish))
                            dic.Add("finish", fo.Finish);
                        itemList.Add(dic);
                        break;
                    case "DropOut":
                        dic = new Dictionary<string, object>();
                        DropOut d = (DropOut)eff;
                        dic.Add("effect", d.Name);
                        dic.Add("toggle", d.Toggle);
                        dic.Add("runMode", (int)d.RunMode);
                        if (!string.IsNullOrEmpty(d.Setup))
                            dic.Add("setup", d.Setup);
                        if (!string.IsNullOrEmpty(d.Finish))
                            dic.Add("finish", d.Finish);
                        itemList.Add(dic);
                        break;
                    case "Puff":
                        dic = new Dictionary<string, object>();
                        Puff pf = (Puff)eff;
                        dic.Add("effect", pf.Name);
                        dic.Add("toggle", pf.Toggle);
                        dic.Add("runMode", (int)pf.RunMode);
                        if (!string.IsNullOrEmpty(pf.Setup))
                            dic.Add("setup", pf.Setup);
                        if (!string.IsNullOrEmpty(pf.Finish))
                            dic.Add("finish", pf.Finish);
                        itemList.Add(dic);
                        break;
                    case "Pulsate":
                        dic = new Dictionary<string, object>();
                        Pulsate p = (Pulsate)eff;
                        dic.Add("effect", p.Name);
                        dic.Add("transition", ToPascalCase(p.Transition.ToString()));
                        dic.Add("duration", p.Duration);
                        dic.Add("from", GetUnitValueIfPercent(p.From));
                        dic.Add("to", GetUnitValueIfPercent(p.To));
                        dic.Add("runMode", (int)p.RunMode);
                        if (!string.IsNullOrEmpty(p.Setup))
                            dic.Add("setup", p.Setup);
                        if (!string.IsNullOrEmpty(p.Finish))
                            dic.Add("finish", p.Finish);
                        itemList.Add(dic);
                        break;

                }
            }
            return itemList.Count > 0 ? itemList : null;
        }

        static string GetUnitValueIfPercent(Unit u)
        {
            if (u.Type == UnitType.Percentage)
                return u.ToString();
            return u.Value.ToString();
        }

        static string ToPascalCase(string s)
        {
            if (string.IsNullOrEmpty(s))
                return s;
            return s.Substring(0, 1).ToLower() + s.Substring(1);
        }

        #endregion Methods
    }
}